using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.ComponentModel;
using System.Reflection;
using System.IO;
namespace DTO
{
    /// <summary> 
    ///Author: nnamthach@gmail.com 
    /// <summary>

    public class DTOInfo
    {
        #region Local Variable

        #endregion LocalVariable

        #region Constructor
        public DTOInfo() { }
        public virtual void LoadDataRow(DataRow dr)
        {
            foreach (PropertyInfo p in this.GetType().GetProperties())
            {
                string name = GetFieldName(p);
                if (dr.Table.Columns.Contains(name) && dr[name] != DBNull.Value)
                {
                    p.SetValue(this, Convert.ChangeType(dr[name], GetGenericType(p.PropertyType)), null);
                }
            }
        }
        public void LoadDataRow(DataRowView dv) { LoadDataRow(dv.Row); }

        //public virtual void Set(DTOInfo objEntr)
        //{
        //    _db = objEntr.db;
        //}

        //public virtual void Set(params object[] objs)
        //{
        //    if (objs != null && objs.Length > 0)
        //    {
        //        _db = objs[0].ToString();
        //    }
        //}
        public DTOInfo(DTOInfo objEntr)
        {
            foreach (PropertyInfo p in this.GetType().GetProperties())
            {
                PropertyInfo px = this.GetType().GetProperty(p.Name);
                p.SetValue(this, px.GetValue(objEntr, null), null);
            }
        }

        public virtual bool isField(string field)
        {
            foreach (PropertyInfo p in this.GetType().GetProperties())
            {
                if (field == GetFieldName(p)) return true;
            }

            return false;
        }

        //public virtual void Restore(DTOInfo objEntr)
        //{
        //    Set(objEntr);

        //    //if (_details != null && objEntr._details != null)
        //    //{
        //    //    _details.Clear();

        //    //    foreach (DTOInfo it in objEntr._details)
        //    //    {
        //    //        DTOInfo a = it.Dulicate();
        //    //        _details.Add(a);
        //    //        a.PropertyChanged += new PropertyChangedEventHandler(details_PropertyChanged);
        //    //    }
        //    //}


        //}

        //protected virtual DTOInfo Dulicate()
        //{
        //    DTOInfo inf = new DTOInfo();
        //    inf.Set(this);
        //    return inf;
        //}

        #endregion Constructor

        #region InitTable

        public virtual DataTable ToDataTable()
        {
            DataTable dt = new DataTable(this.GetType().Name);
            foreach (PropertyInfo p in this.GetType().GetProperties())
            {
                if (!p.PropertyType.IsArray) dt.Columns.Add(GetFieldName(p), GetGenericType(p.PropertyType));
            }
            return dt;
        }
        public static Type GetGenericType(Type t)
        {
            if (t.IsGenericType && t.GetGenericTypeDefinition() == typeof(Nullable<>))
                return t.GetGenericArguments()[0];

            return t;
        }
        private static String GetFieldName(PropertyInfo info)
        {
            object[] attributes = info.GetCustomAttributes(typeof(FieldNameAttribute), false);
            if (attributes != null && attributes.Length > 0)
            {
                var displayName = (FieldNameAttribute)attributes[0];
                return displayName.FieldName;
            }
            return info.Name;

        }
        public virtual DataRow ToDataRow(DataTable dt)
        {
            DataRow row = dt.NewRow();
            foreach (PropertyInfo p in this.GetType().GetProperties())
            {
                string name = GetFieldName(p);
                if (dt.Columns.Contains(name) && p != null && p.GetValue(this, null) != null)
                {
                    row[name] = p.GetValue(this, null);
                }
            }

            return row;
        }

        #endregion InitTable

        public static DateTime NullDate = new DateTime(1911, 1, 1);

        public object GetValue(string name)
        {
            object res = null;
            PropertyInfo p = this.GetType().GetProperty(name);
            if (p != null) res = p.GetValue(this, null);
            return p;
        }
        public void AddValue(string name, int count)
        {
            PropertyInfo p = this.GetType().GetProperty(name);
            if (p != null)
            {
                object o = p.GetValue(this, null);
                if (o != null)
                {
                    int val = Convert.ToInt32(o) + count;
                    p.SetValue(this, val, null);
                }
            }
        }
        public void SetValue(string name, object count)
        {
            PropertyInfo p = this.GetType().GetProperty(name);
            if (p != null)
            {
                p.SetValue(this, count, null);
            }
        }
    }
}
